﻿using Devonline.Communication.Abstractions;

namespace Devonline.Communication.Modbus;

/// <summary>
/// Modbus 协议基础接口
/// </summary>
public interface IModbusCommunicator : IStreamCommunicator
{
    /// <summary>
    /// 使能状态
    /// </summary>
    public bool Enable { get; }

    /// <summary>
    /// 读取离散输入寄存器的值
    /// </summary>
    /// <param name="address">寄存器地址</param>
    /// <returns></returns>
    Task<bool> ReadInputAsync(ushort address);
    /// <summary>
    /// 读取离散输入寄存器的值
    /// </summary>
    /// <param name="address">起始地址</param>
    /// <param name="numberOfPoints">读取数量</param>
    /// <returns></returns>
    Task<bool[]> ReadInputsAsync(ushort address, ushort numberOfPoints);

    /// <summary>
    /// 读取线圈寄存器的值
    /// </summary>
    /// <param name="address">寄存器地址</param>
    /// <returns></returns>
    Task<bool> ReadCoilAsync(ushort address);
    /// <summary>
    /// 读取线圈寄存器的值
    /// </summary>
    /// <param name="address">起始地址</param>
    /// <param name="numberOfPoints">读取数量</param>
    /// <returns></returns>
    Task<bool[]> ReadCoilsAsync(ushort address, ushort numberOfPoints);

    /// <summary>
    /// 读取输入寄存器的值
    /// </summary>
    /// <param name="address">寄存器地址</param>
    /// <returns></returns>
    Task<ushort> ReadInputRegisterAsync(ushort address);
    /// <summary>
    /// 读取输入寄存器数据
    /// </summary>
    /// <param name="address">起始地址</param>
    /// <param name="numberOfPoints">读取数量</param>
    /// <returns></returns>
    Task<ushort[]> ReadInputRegistersAsync(ushort address, ushort numberOfPoints);

    /// <summary>
    /// 读取保持寄存器的值
    /// </summary>
    /// <param name="address">寄存器地址</param>
    /// <returns></returns>
    Task<ushort> ReadHoldingRegisterAsync(ushort address);
    /// <summary>
    /// 读取保持寄存器的数据
    /// </summary>
    /// <param name="address">起始地址</param>
    /// <param name="numberOfPoints">读取数量</param>
    /// <returns></returns>
    Task<ushort[]> ReadHoldingRegistersAsync(ushort address, ushort numberOfPoints);

    /// <summary>
    /// 写入值到线圈寄存器
    /// </summary>
    /// <param name="address">寄存器地址</param>
    /// <param name="value">值</param>
    /// <returns></returns>
    Task WriteCoilAsync(ushort address, bool value);
    /// <summary>
    /// 写入数据到线圈寄存器
    /// </summary>
    /// <param name="address">起始地址</param>
    /// <param name="data">值</param>
    /// <returns></returns>
    Task WriteCoilsAsync(ushort address, params bool[] data);

    /// <summary>
    /// 写入值到保持寄存器
    /// </summary>
    /// <param name="address">寄存器地址</param>
    /// <param name="value">写入的值</param>
    /// <returns></returns>
    Task WriteRegisterAsync(ushort address, ushort value);
    /// <summary>
    /// 写入数据到保持寄存器
    /// </summary>
    /// <param name="address">起始地址</param>
    /// <param name="data">写入的数据</param>
    /// <returns></returns>
    Task WriteRegistersAsync(ushort address, params ushort[] data);

    /// <summary>
    /// 连续执行某一任务, 直到成功或则到达最大尝试次数后退出
    /// </summary>
    /// <param name="task">需要执行的任务</param>
    /// <returns></returns>
    Task<bool> ExecuteAsync(Func<Task<bool>> task);
}